#!/bin/bash
#------------------------------------------
# desc:
#     openssl命令封装
# author:
#     dockerlin@163.com
# ------------------------------------------

function cxlib_openssl(){
    logger_debug "checking command openssl!"
    command -v "openssl" >/dev/null 2>&1
    retval=$?
    if [ $retval -gt 0 ]; then 
        logger_error "command openssl has not installed,please checked and reload this file!"
    fi
    return $retval
}
# ----------------------------
# 返回随机字符串
# openssl rand -base64 10
# openssl rand -hex 10
# 调用方式 cxlib_openssl_rand 输出方式 输出位数
#         str=`cxlib_openssl_rand "base64" 10` 
#         str=`cxlib_openssl_rand "hex" 10`
# ----------------------------
cxlib_openssl_rand(){
    local status=0
    outpuType="hex";outputNum=10;
    if [ -n "$1" ] ; then outpuType="$1"; fi
    if [ -n "$2" ] ; then outputNum="$2"; fi
    openssl rand -${outpuType} ${outputNum} && status=0 || status=1
    logger_debug "返回随机字符串：openssl rand -${outpuType} ${outputNum}"
    unset outpuType outputNum
    return ${status}
}

# ----------------------------
# 返回字符串摘要值
# echo -n "admin" | openssl md5 -binary | od -tx1 -w1 | awk 'NF<2{next}{printf("%s",$2)}'
# echo -n "admin" | openssl md5 | awk '{printf("%s",$2)}'
# echo -n "admin" | openssl dgst -md5 | awk '{printf("%s",$2)}'
# 调用方式 cxlib_openssl_digest 带加密的字符串 true|false(是否转换为16进制） 加密算法(md5 sha1)
#          md5_str=`cxlib_openssl_digest "1234567"` 
#          sha1_str=`cxlib_openssl_digest "1234567" "sha1"` 
# ----------------------------
cxlib_openssl_digest(){
    if [ -z "$1" ] ; then return 1; fi
    # 确定摘要算法，缺省md5
    digest_algorithm='md5'
    if [ -n "$2" ] ; then digest_algorithm="$2"; fi
    local status=0
    echo -n "$1" | openssl dgst -${digest_algorithm} | awk '{printf("%s",$2)}' && status=0 || status=1
    logger_debug "生成${digest_algorithm}摘要：echo -n $1 | openssl dgst -${digest_algorithm} | awk '{printf(\"%s\",$2)}'"
    unset digest_algorithm
    return $status
}


# ----------------------------
# 返回字符串md5值
# 调用方式 cxlib_openssl_md5 带加密的字符串 
#          md5_str=`cxlib_openssl_md5 "1234567"` || echo "fail"
# ----------------------------
cxlib_openssl_md5(){
    cxlib_openssl_digest "$1" "md5"
    return $?
}

# ----------------------------
# 返回字符串md5值
# 调用方式 cxlib_openssl_sha1 带加密的字符串 
#          md5_str=`cxlib_openssl_sha1 "1234567"` || echo "fail"
# ----------------------------
cxlib_openssl_sha1(){
    cxlib_openssl_digest "$1" "sha1"
    return $?
}

# ----------------------------
# 返回加密后的字符串
# 缺省加密算法 aes-128-ecb
# 支持输出base64和16进制字符串 缺省16进制字符串 （base64 or hex）
# echo -n "1234567"|openssl enc -e -aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 | od -tx1 -w1 -v | awk 'NF<2{next}{printf("%s",$2)}' | tr '[a-z]' '[A-Z]'
# echo -n "1234567"|openssl aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 | od -tx1 | awk '{for(i=2;i<=NF;i++){printf("%s",$i);}}'
# 196d7e3754c5814d4c868c38e951f588
# 调用方式 result=`cxlib_openssl_encrypt 待加密的字符串 秘钥 加密算法（缺省） 输出的字符串编码类型`
#         result=`cxlib_openssl_encrypt "1234567" 226a89e66d0dcc79c9673150fa176001 "aes-128-ecb"`
# ----------------------------
cxlib_openssl_encrypt(){
    if [ -z "$1" ] ; then return 1; fi
    if [ -z "$2" ] ; then return 2; fi
    encrypt_algorithm="aes-128-ecb"
    if [ -n "$3" ] ; then encrypt_algorithm="$3"; fi
    outpuType="hex"
    if [ -n "$4" ] ; then outpuType="$4"; fi
    local status=1
    case $outpuType in
        hex)  
            echo -n "$1" | openssl enc -e -${encrypt_algorithm} -K $2 | od -tx1 | awk '{for(i=2;i<=NF;i++){printf("%s",$i);}}' && status=0 || status=1
            logger_debug "生成16进制加密字符串：echo -n \"$1\"|openssl enc -e -${encrypt_algorithm} -K $2 | od -tx1 | awk '{for(i=2;i<=NF;i++){printf(\"%s\",$i);}}'"
        ;;
        base64)  
            echo -n "$1" | openssl enc -e -${encrypt_algorithm} -K $2 -a -A
            logger_debug "生成base64编码加密字符串：echo -n \"$1\"|openssl enc -e -${encrypt_algorithm} -K $2 -a -A" && status=0 || status=1
        ;;
        *)  
            echo -n "$1" | openssl enc -e -${encrypt_algorithm} -K $2 | od -tx1 | awk '{for(i=2;i<=NF;i++){printf("%s",$i);}}' && status=0 || status=1
            logger_debug "生成16进制加密字符串：echo -n \"$1\"|openssl enc -e -${encrypt_algorithm} -K $2 | od -tx1 | awk '{for(i=2;i<=NF;i++){printf(\"%s\",$i);}}'"
        ;;
    esac
    #echo -n "$1"|openssl aes-128-ecb -K $2 | od -tx1 -w1 -v | awk 'NF<2{next}{printf("%s",$2)}' | tr '[a-z]' '[A-Z]' && status=0 || status=1   
    return $status
}

# ----------------------------
# 返回解密后的字符串
# echo 196D7E3754C5814D4C868C38E951F588 | sed 's/\(..\)/\\\\x\1/g' | xargs echo -e -n | openssl aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 -d
# echo -n "GW1+N1TFgU1Mhow46VH1iA==" | openssl enc -d -aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 -a -A
# 调用方式 result=`cxlib_openssl_decrypt 待解密的字符串 秘钥 加密算法（缺省aes-128-ecb）输入的字符串编码类型`
#         result=`cxlib_openssl_decrypt "196d7e3754c5814d4c868c38e951f588" 226a89e66d0dcc79c9673150fa176001 "aes-128-ecb"`
# ----------------------------
cxlib_openssl_decrypt(){
    if [ -z "$1" ] ; then return 1; fi
    if [ -z "$2" ] ; then return 2; fi
    encrypt_algorithm="aes-128-ecb"
    if [ -n "$3" ] ; then encrypt_algorithm="$3"; fi
    outpuType="hex"
    if [ -n "$4" ] ; then outpuType="$4"; fi
    local status=1
    case $outpuType in
        hex) 
            echo -n "$1" | sed 's/\(..\)/\\\\x\1/g' | xargs echo -e -n | openssl enc -d -${encrypt_algorithm} -K $2  && status=0 || status=1
            logger_debug "解密16进制字符串：echo -n \"$1\"| sed 's/\\(..\\)/\\\\\\\\x\\1/g' | xargs echo -e -n | openssl enc -d -${encrypt_algorithm} -K $2"
        ;;
        base64)  
            echo -n "$1" | openssl enc -d -${encrypt_algorithm} -K $2 -a -A
            logger_debug "解密base64字符串：echo -n \"$1\"|openssl enc -d -${encrypt_algorithm} -K $2 -a -A" && status=0 || status=1
        ;;
        *)  
            echo -n "$1" | sed 's/\(..\)/\\\\x\1/g' | xargs echo -e -n | openssl enc -d -${encrypt_algorithm} -K $2  && status=0 || status=1
            logger_debug "解密16进制字符串：echo -n \"$1\"| sed 's/\\(..\\)/\\\\\\\\x\\1/g' | xargs echo -e -n | openssl enc -d -${encrypt_algorithm} -K $2"
        ;;
    esac 
    return $status
}